<?php

namespace App\Http\Controllers\Admin;

use App\Models\Goods;
use App\Models\GoodsAddress;
use App\Models\GoodsImg;
use App\Models\GoodsOrder;
use App\Models\Manage;
use App\Validate\GoodsValidate;
use Illuminate\Support\Facades\DB;

/**
 * 商品管理
 */
class GoodsController extends CommonController
{

    public $model = null;
    public $validate = null;

    public function __construct()
    {
        parent::__construct();

        $this->model = new Goods();
        $this->validate = new GoodsValidate();
    }

    /**
     * 列表
     * @param page int 当前页
     * @param limit int 分页大小
     * @param is_number int 兑换次数 0全部 1无限次 2有限次
     * @param keywords string 关键词查询(商品名称)
     * @param send_way int 兑换方式 0 全部 (1 自提 2 邮递  3、2者都可以)
     * @param start_time datetime 创建时间范围搜索(开始)
     * @param end_time datetime 创建时间范围搜索(结束)
     * @param type_id int 商品类型id
     */
    public function lists()
    {
        $app_goods_expire_time = config('other.app_goods_expire_time');
        if ($app_goods_expire_time && $app_goods_expire_time < date('Y-m-d')) {
            $app_goods_expire_msg = config('other.app_goods_expire_msg') ? config('other.app_goods_expire_msg') : '试用已过期！';
            return $this->returnApi(202, $app_goods_expire_msg); //使用过期，什么都不能使用
        }

        $page = $this->request->page ? intval($this->request->page) : 1;
        $limit = $this->request->limit ? intval($this->request->limit) : 10;
        $is_number = $this->request->is_number;
        $keywords = $this->request->keywords;
        $send_way = $this->request->send_way;
        $start_time = $this->request->start_time;
        $end_time = $this->request->end_time;
        $type_id = $this->request->type_id;

        $condition[] = ['is_del', '=', 1];

        if ($type_id) {
            $condition[] = ['type_id', '=', $type_id];
        }

        if ($start_time && $end_time) {
            $condition[] = ['create_time', '>=', $start_time];
            $condition[] = ['create_time', '<=', $end_time];
        }

        if ($keywords) {
            $condition[] = ['name', 'like', "%$keywords%"];
        }

        if ($is_number == 2) {
            $condition[] = ['times', '<>', 0];
        }

        if ($is_number == 1) {
            $condition[] = ['times', '=', 0];
        }


        $res = $this->model
            ->select('id', 'name', 'type_id', 'img', 'score', 'price', 'score', 'number', 'has_number', 'cancel_end_time', 'times', 'tel', 'contacts', 'send_way', 'start_time', 'end_time', 'pick_end_time', 'is_play', 'intro', 'manage_id', 'create_time', 'change_time')
            ->with(['conType' => function ($query) {
                $query->select('id', 'type_name');
            }, 'conManage' => function ($query) {
                $query->select('id', 'username', 'account');
            }, 'conImg'])
            ->where($condition)
            ->where(function ($query) use ($send_way) {
                if ($send_way) {
                    $query->where('send_way', $send_way);
                }
            })
            ->orderByDesc('create_time')
            ->paginate($limit)
            ->toArray();

        if (empty($res['data'])) {
            return $this->returnApi(203, "暂无数据");
        }

        /**获取自提地址 */
        $goodsAddressModel = new GoodsAddress();
        $goods_address = $goodsAddressModel->find(1);


        if ($res['data']) {
            $res = $this->disPageData($res);
            $res['data'] = $this->disDataSameLevel($res['data'], 'con_type', ['type_name' => 'type_name']);
            $res['data'] = $this->disDataSameLevel($res['data'], 'con_manage', [Manage::$manage_name => 'manage_name']);
            //增加序号
            $res['data'] = $this->addSerialNumber($res['data'], $page, $limit);

            $res['pick_address'] = $goods_address; //赋值自提地址

            return $this->returnApi(200, '获取成功', true, $res);
        }

        return $this->returnApi(203, '暂无数据');
    }

    /**
     * 详情
     * @param id int 商品id
     */
    public function detail()
    {
        $app_goods_expire_time = config('other.app_goods_expire_time');
        if ($app_goods_expire_time && $app_goods_expire_time < date('Y-m-d')) {
            $app_goods_expire_msg = config('other.app_goods_expire_msg') ? config('other.app_goods_expire_msg') : '试用已过期！';
            return $this->returnApi(202, $app_goods_expire_msg); //使用过期，什么都不能使用
        }
        //增加验证场景进行验证
        if (!$this->validate->scene('detail')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $res = $this->model
            ->select('id', 'name', 'type_id', 'img', 'score', 'price', 'score', 'number', 'has_number', 'times', 'tel', 'cancel_end_time', 'contacts', 'send_way', 'start_time', 'end_time', 'pick_end_time', 'is_play', 'intro', 'manage_id', 'create_time')
            ->with(['conType' => function ($query) {
                $query->select('id', 'type_name');
            }, 'conManage' => function ($query) {
                $query->select('id', 'username', 'account');
            }, 'conImg' => function ($query) {
                $query->select('id', 'goods_id', 'img', 'thumb_img');
            }])
            ->where('is_del', 1)
            ->find($this->request->id);


        if (!$res) {
            return $this->returnApi(201, "参数传递错误");
        }
        $res = $res->toArray();

        $res = $this->disDataSameLevel($res, 'con_manage', [Manage::$manage_name => 'manage_name']);
        $res = $this->disDataSameLevel($res, 'con_type', ['type_name' => 'type_name']);


        return $this->returnApi(200, "查询成功", true, $res);
    }

    /**
     * 新增
     * @param name string 商品名称
     * @param type_id int 商品类型id
     * @param img string 商品封面
     * @param intro string 商品简介
     * @param score int 兑换商品所需积分
     * @param price int 除去积分还需支付金额
     * @param number int 商品数量
     * @param times int 用户可兑商品换次数  0 表示不限
     * @param tel string 联系电话
     * @param contacts string 联系人
     * @param send_way int 商品运送方式 1 自提 2 邮递  3、2者都可以
     * @param start_time datetime 开始兑换时间
     * @param end_time datetime 结束兑换时间
     * @param pick_end_time datetime 自提截止时间
     * @param cancel_end_time int 支付成功后，可取消的最后期限  单位 分钟  0 为  不可以取消
     * @param imgs string 商品图片用‘|’分割
     */
    public function add()
    {
        $app_goods_expire_time = config('other.app_goods_expire_time');
        if ($app_goods_expire_time && $app_goods_expire_time < date('Y-m-d')) {
            $app_goods_expire_msg = config('other.app_goods_expire_msg') ? config('other.app_goods_expire_msg') : '试用已过期！';
            return $this->returnApi(202, $app_goods_expire_msg); //使用过期，什么都不能使用
        }
        //增加验证场景进行验证
        if (!$this->validate->scene('add')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $is_exists = $this->model->nameIsExists($this->request->name, 'name');

        if ($is_exists) {
            return $this->returnApi(202, "此名称已存在");
        }

        /**
         * 自提需要设置截止时间
         */
        if (($this->request->send_way == 1 || $this->request->send_way == 3)) {
            if (!$this->request->pick_end_time) {
                return $this->returnApi(201, '请设置商品自提截止时间');
            }
            if ($this->request->end_time > $this->request->pick_end_time) {
                return $this->returnApi(201, '自提截止时间必须大于兑换结束时间');
            }
        }


        $data = [
            'name' => $this->request->name,
            'type_id' => $this->request->type_id,
            'img' => $this->request->img,
            'intro' => $this->request->intro,
            'score' => $this->request->score,
            'price' => $this->request->price,
            'number' => $this->request->number,
            'times' => $this->request->times,
            'tel' => $this->request->tel,
            'contacts' => $this->request->contacts,
            'send_way' => $this->request->send_way,
            'start_time' => $this->request->start_time,
            'end_time' => $this->request->end_time,
            'pick_end_time' => $this->request->pick_end_time,
            'cancel_end_time' => empty($this->request->cancel_end_time) ? 0 : $this->request->cancel_end_time,
            'manage_id' => $this->request->manage_id,
        ];

        DB::beginTransaction();
        try {
            $this->model->add($data);
            //添加图片
            if ($this->request->imgs) {
                $goodsImgModel = new GoodsImg();
                $goodsImgModel->goodsImgChange($this->model->id, $this->request->imgs, 'add');
            }

            DB::commit();
            return $this->returnApi(200, "新增成功", true);
        } catch (\Exception $e) {
            //var_dump($e->getMessage());exit;
            // 回滚事务
            DB::rollBack();
            return $this->returnApi(202, "新增失败");
        }
    }

    /**
     * 编辑
     * @param id int 商品id
     * @param name string 商品名称
     * @param type_id int 商品类型id
     * @param img string 商品封面
     * @param intro string 商品简介
     * @param score int 兑换商品所需积分
     * @param price int 除去积分还需支付金额
     * @param number int 商品数量
     * @param times int 用户可兑商品换次数
     * @param tel string 联系电话
     * @param contacts string 联系人
     * @param send_way int 商品运送方式 1 自提 2 邮递  3、2者都可以
     * @param start_time datetime 开始兑换时间
     * @param end_time datetime 结束兑换时间
     * @param pick_end_time datetime 自提截止时间
     * @param cancel_end_time datetime 自提截止时间
     * @param imgs string 商品图片用‘|’分割  (只传新增的)
     */
    public function change()
    {
        $app_goods_expire_time = config('other.app_goods_expire_time');
        if ($app_goods_expire_time && $app_goods_expire_time < date('Y-m-d')) {
            $app_goods_expire_msg = config('other.app_goods_expire_msg') ? config('other.app_goods_expire_msg') : '试用已过期！';
            return $this->returnApi(202, $app_goods_expire_msg); //使用过期，什么都不能使用
        }

        //增加验证场景进行验证
        if (!$this->validate->scene('change')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $goods = $this->model->where('is_del', 1)->find($this->request->id);
        if (!$goods) {
            return $this->returnApi(201, '参数传递错误');
        }
        if ($goods->is_play == 1) {
            return $this->returnApi(202, '请先下架商品再进行编辑');
        }

        //获取商品兑换次数
        if ($this->request->send_way != $goods->send_way && !empty($goods['has_number'])) {
            if (!empty($conversion_number)) {
                return $this->returnApi(201, '此商品已有人兑换，不能修改领取方式');
            }
        }
        if ($this->request->number < $goods['has_number']) {
            return $this->returnApi(201, '商品数量不能小于已兑换数量');
        }

        $is_exists = $this->model->nameIsExists($this->request->name, 'name', $this->request->id);

        if ($is_exists) {
            return $this->returnApi(202, "此名称已存在");
        }
        if ($goods->end_time != $this->request->end_time && $this->request->end_time < date('Y-m-d H:i:s')) {
            return $this->returnApi(201, '兑换结束时间不能小于当前时间');
        }

        /**
         * 自提需要设置截止时间
         */
        if (($this->request->send_way == 1 || $this->request->send_way == 3)) {
            if (!$this->request->pick_end_time) {
                return $this->returnApi(201, '请设置商品自提截止时间');
            }
            if ($this->request->end_time > $this->request->pick_end_time) {
                return $this->returnApi(201, '自提截止时间必须大于兑换结束时间');
            }
        }

        $data = [
            'id' => $this->request->id,
            'name' => $this->request->name,
            'type_id' => $this->request->type_id,
            'img' => $this->request->img,
            'intro' => $this->request->intro,
            'score' => $this->request->score,
            'price' => $this->request->price,
            'number' => $this->request->number,
            'times' => $this->request->times,
            'tel' => $this->request->tel,
            'contacts' => $this->request->contacts,
            'send_way' => $this->request->send_way,
            'start_time' => $this->request->start_time,
            'end_time' => $this->request->end_time,
            'pick_end_time' => $this->request->pick_end_time,
            'cancel_end_time' => empty($this->request->cancel_end_time) ? 0 : $this->request->cancel_end_time,
        ];


        DB::beginTransaction();
        try {
            $this->model->change($data);

            //处理图片
            $goodsImgModel = new GoodsImg();
            $del_arr_img = $goodsImgModel->goodsImgChange($this->request->id, $this->request->imgs, 'change');
            foreach ($del_arr_img as $key => $val) {
                $this->deleteFile($val);
                $this->deleteFile(str_replace('.', '_thumb.', $val));
            }

            DB::commit();
            return $this->returnApi(200, "修改成功", "YES");
        } catch (\Exception $e) {
            // 回滚事务
            DB::rollBack();
            return $this->returnApi(202, "修改失败", "YES");
        }
    }


    /**
     * 删除
     * @param id int 商品id
     */
    public function del()
    {
        $app_goods_expire_time = config('other.app_goods_expire_time');
        if ($app_goods_expire_time && $app_goods_expire_time < date('Y-m-d')) {
            $app_goods_expire_msg = config('other.app_goods_expire_msg') ? config('other.app_goods_expire_msg') : '试用已过期！';
            return $this->returnApi(202, $app_goods_expire_msg); //使用过期，什么都不能使用
        }
        //增加验证场景进行验证
        if (!$this->validate->scene('del')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $id = $this->request->id;

        $goods = $this->model->find($id);


        if (!$goods) {
            return $this->returnApi(201, '参数传递错误');
        }

        $goodsOrderModel = new GoodsOrder();
        //获取商品兑换次数
        $conversion_number = $goodsOrderModel->getConversionNumber(null, $id);
        if (!empty($conversion_number)) {
            return $this->returnApi(201, '此商品已有人兑换，请勿删除');
        }


        if ($goods->is_play == 1) {
            return $this->returnApi(202, '请先下架商品再进行删除');
        }

        $goods->is_del = 2;
        $res = $goods->save();

        if (!$res) {
            return $this->returnApi(202, "删除失败");
        }

        return $this->returnApi(200, "删除成功", true);
    }

    /**
     * 上架、下架商品
     * @param ids array 商品品id  多个 逗号拼接  is_all为 2 才有效
     * @param is_play int 操作 1 上架  2下架
     * @param is_all int 是否全部上下架 1是 2否
     */
    public function goodsOnAndOff()
    {
        $app_goods_expire_time = config('other.app_goods_expire_time');
        if ($app_goods_expire_time && $app_goods_expire_time < date('Y-m-d')) {
            $app_goods_expire_msg = config('other.app_goods_expire_msg') ? config('other.app_goods_expire_msg') : '试用已过期！';
            return $this->returnApi(202, $app_goods_expire_msg); //使用过期，什么都不能使用
        }

        //增加验证场景进行验证
        if (!$this->validate->scene('goodsOnAndOff')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $ids = $this->request->ids;
        $is_play = $this->request->is_play;
        $is_all = $this->request->is_all;

        if ($is_all == 2 && empty($ids)) {
            return $this->returnApi(201, '商品id不能为空');
        }

        if ($is_play == 2) {
            $msg = '下架';
        } else {
            $msg = '上架';
        }

        if ($is_all == 1) {
            $res = $this->model->where('is_del', 1)->update(['is_play' => $is_play, 'change_time' => date('Y-m-d H:i:s')]);
        } else {
            $ids = explode(',', $ids);
            $res = $this->model->where('is_del', 1)->whereIn('id', $ids)->update(['is_play' => $is_play, 'change_time' => date('Y-m-d H:i:s')]);
        }

        if (!$res) {
            return $this->returnApi(202, $msg . "失败");
        }

        return $this->returnApi(200, $msg . "成功", true);
    }

    /**
     * 获取商品自提地址
     */
    public function getGoodsPickAddress()
    {
        $app_goods_expire_time = config('other.app_goods_expire_time');
        if ($app_goods_expire_time && $app_goods_expire_time < date('Y-m-d')) {
            $app_goods_expire_msg = config('other.app_goods_expire_msg') ? config('other.app_goods_expire_msg') : '试用已过期！';
            return $this->returnApi(202, $app_goods_expire_msg); //使用过期，什么都不能使用
        }

        /**获取自提地址 */
        $goodsAddressModel = new GoodsAddress();
        $address = $goodsAddressModel->find(1);

        if (!$address) {
            return $this->returnApi(203, "暂无数据");
        }
        return $this->returnApi(200, "查询成功", true, $address);
    }

    /**
     * 设置商品自提地址
     * @param province string 省
     * @param city string 市
     * @param district string 区
     * @param street string 街道
     * @param address string 详细地址
     * @param tel string 联系电话
     * @param contacts string 联系人
     */
    public function setGoodsPickAddress()
    {
        $app_goods_expire_time = config('other.app_goods_expire_time');
        if ($app_goods_expire_time && $app_goods_expire_time < date('Y-m-d')) {
            $app_goods_expire_msg = config('other.app_goods_expire_msg') ? config('other.app_goods_expire_msg') : '试用已过期！';
            return $this->returnApi(202, $app_goods_expire_msg); //使用过期，什么都不能使用
        }

        //增加验证场景进行验证
        if (!$this->validate->scene('setGoodsPickAddress')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }
        /**获取自提地址 */
        $goodsAddressModel = new GoodsAddress();
        $address = $goodsAddressModel->find(1);

        if (!$address) {
            $address = $goodsAddressModel;
        }
        $address->province = $this->request->province;
        $address->city = $this->request->city;
        $address->district = $this->request->district;
        $address->street = $this->request->street;
        $address->address = $this->request->address;
        $address->tel = $this->request->tel;
        $address->contacts = $this->request->contacts;
        $res = $address->save();

        if ($res) {
            return $this->returnApi(200, "设置成功", true);
        }
        return $this->returnApi(202, "设置失败");
    }
}
